package com.diu.domain.strategy.service.raffle;

import com.diu.domain.strategy.model.entity.RaffleAwardEntity;
import com.diu.domain.strategy.model.entity.RaffleFactorEntity;
import com.diu.domain.strategy.model.entity.RuleActionEntity;
import com.diu.domain.strategy.model.entity.StrategyEntity;
import com.diu.domain.strategy.model.vo.RuleLogicCheckTypeVO;
import com.diu.domain.strategy.model.vo.StrategyAwardRuleModelVO;
import com.diu.domain.strategy.repository.IStrategyRepository;
import com.diu.domain.strategy.service.IRaffleStrategy;
import com.diu.domain.strategy.service.armory.IStrategyDispatch;
import com.diu.domain.strategy.service.rule.chain.ILogicChain;
import com.diu.domain.strategy.service.rule.chain.factory.DefaultChainFactory;
import com.diu.domain.strategy.service.rule.filter.factory.DefaultLogicFactory;
import com.diu.types.enums.ResponseCode;
import com.diu.types.exception.AppException;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

/**
 * @author #diu
 * @description #抽奖策略抽象类
 * @create #2025/10/10 10:58
 */

public abstract class AbstractRaffleStrategy implements IRaffleStrategy {

    // 策略仓储服务 -> domain层像一个大厨，仓储层提供米面粮油
    protected IStrategyRepository repository;
    // 策略调度服务 -> 只负责抽奖处理，通过新增接口的方式，隔离职责，不需要使用方关心或者调用抽奖的初始化
    protected IStrategyDispatch strategyDispatch;

    protected DefaultChainFactory chainFactory;

    public AbstractRaffleStrategy(IStrategyRepository repository, IStrategyDispatch strategyDispatch, DefaultChainFactory chainFactory) {
        this.repository = repository;
        this.strategyDispatch = strategyDispatch;
        this.chainFactory = chainFactory;
    }

    @Override
    public RaffleAwardEntity doRaffle(RaffleFactorEntity raffleFactorEntity) {
        // 1.参数校验
        String userId = raffleFactorEntity.getUserId();
        Long strategyId = raffleFactorEntity.getStrategyId();
        if(null == strategyId || StringUtils.isBlank(userId)){
            throw new AppException(ResponseCode.ILLEGAL_PARAMETER.getCode(), ResponseCode.ILLEGAL_PARAMETER.getInfo());
        }

        // 2.责任链抽奖
        ILogicChain logicChain = chainFactory.openLogicChain(strategyId);
        Integer awardId = logicChain.logic(userId, strategyId);

        // 3.查询奖品规则【抽奖中（拿到奖品ID时，过滤规则】【抽奖后（扣减完奖品库存后过滤，抽奖中拦截和无库存则走兜底】
        StrategyAwardRuleModelVO strategyAwardRuleModelVO = repository.queryStrategyAwardRuleModel(strategyId, awardId);
        if(strategyAwardRuleModelVO == null) return RaffleAwardEntity.builder()
                                            .awardId(awardId)
                                            .build();

        // 4.抽奖中 - 规则过滤
        String[] raffleMiddleRuleModelList = strategyAwardRuleModelVO.raffleMiddleRuleModelList();
        RuleActionEntity<RuleActionEntity.RaffleMiddleEntity> ruleMiddleEntity = this.doCheckRaffleMiddleLogic(RaffleFactorEntity.builder().userId(userId).awardId(awardId).strategyId(strategyId).build(), raffleMiddleRuleModelList);
        if(ruleMiddleEntity.getCode().equals(RuleLogicCheckTypeVO.TAKE_OVER.getCode())){
            if(DefaultLogicFactory.LogicModel.RULE_LOCK.getCode().equals(ruleMiddleEntity.getRuleModel())){
                // 锁定规则，直接返回对应奖品
                return RaffleAwardEntity.builder()
                        .awardDesc("中奖中规则拦截，通过抽奖后规则 rule_luck_award 走兜底奖励")
                        .build();
            }
        }

        if(null != awardId){
            return RaffleAwardEntity.builder()
                    .awardId(awardId)
                    .build();
        }
        return null;
    }

    protected abstract RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> doCheckRaffleBeforeLogic(RaffleFactorEntity raffleFactorEntity, String[] logic);

    protected abstract RuleActionEntity<RuleActionEntity.RaffleMiddleEntity> doCheckRaffleMiddleLogic(RaffleFactorEntity raffleFactorEntity, String[] logic);

}
